// X10ViewPanel.java

/*
**  Licensed Materials - Property of IBM
**
**  (C) COPYRIGHT IBM Corp. 1996, 1997  All rights reserved
**
**  US Government Users Restricted Rights - Use, duplication or
**  disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**/

package	com.ibm.tspaces.examples.x10;

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.util.*;
import com.ibm.tspaces.*;

/**
** The panel of the x10View.
** 
** This handles the main panel where the device panels are placed
** 
**
** All of the TSpaces handling is done inside this object.
** 
** It implements the Tuplespace Callback interface which gets 
** control everytime a matching request is issued to TupleSpace.
**
** 
**  
** @version $Revision: 2.1 $ $Date: 1999/11/05 22:22:41 $
** @author John Thomas
*/
public class X10ViewPanel extends Panel 
		implements Callback {

  protected static Color BACKGROUND_COLOR = Color.white;
 
  private X10View x10View = null;
	
	/**
	** This holds a reference to the current TupleSpace.
	*/
	protected TupleSpace TSServer = null;
	
	/** 
	** This is the Host where the TupleSpace Server is running
	*/
	protected String Host = TupleSpace.DEFAULTHOST;
	protected String TSName = "X10";
	protected boolean NotActive = false;   // set true if server is not active
  protected boolean Failed = false;      // set true if something fails/exception
    

	
    /*
    ***************************************************************************
    ** ** X10ViewPanel **
    ** *********************
    */
    /**
    ** The constructor 
    **
    *************************************************************************** 
    */
    public X10ViewPanel() {
      
        
    } // X10ViewPanel
    
/**
** TupleSpace Initiallization routine.
**
** This will setup to access TupleSpace and register to 
** be informed when anyone writes a "X10Device" tuple to 
** the "X10" tuplespace.
** 
**
*/
public void 
init(X10View caller) {
	// Place the controls at the top of the parent window
	//System.out.println("init entered");
	setLayout(new FlowLayout());


	setBackground(BACKGROUND_COLOR);
  
    
  // Handle the user exiting/killing the application
  if ( caller.appFrame != null ) {
	    caller.appFrame.addWindowListener( new WindowAdapter()  {
	    	public void 
	    	windowClosing (WindowEvent e) {
	    		X10ViewPanel.this.term();    // give it a chance to cleanup
	    		System.exit(0);
	    	}
	    } );
  }

  this.x10View = caller;
  // The host and port may have already been set in x10View.java
  if (X10View.host != null)
       	Host = X10View.host; 
  
					
	int n=0;
	String Msg = null;

 	try {
	
    //--------------------------------------------------
    // Setup to access TupleSpace
    // We access the "X10" tuplespace on the indicatd host.
    // 
		// We then just register for the write event 
		//   X10ViewPanel must implement Callback which will then
		//   be called anytime anyone writes a matching tuple to the tuplespace 
		//------------------------------------------------------------
		Debug.out("Access "+TSName+"@" + Host);
		String user = TupleSpace._DEFAULT_USER;
		String pass = TupleSpace._DEFAULT_PASSWORD;
    //  Tell the TupleSpace code that we are going to be running 
 		//  in an applet sandbox and to avoid any otion that is 
 		//  invalid.
    TupleSpace.appletEnvironment(true);
  
  
    TupleSpace.setConnectionTries(1);
 	
 	  TSServer = new TupleSpace(TSName, Host);

		Debug.out("OK");
		
		
	
	    // create dummy template and do a test read to see if it fails
	  try {
    	Tuple match = new Tuple("X10View"); 
    	        
			Tuple result = TSServer.read(match);
		} catch (TupleSpaceException tse) {
			Debug.out("TSpaces server not running on " + 
						Host );
		    NotActive = true;
		    
		}
 		if (NotActive) {
      Label errmsg = new Label("TSpaces server is not available for communication");
      caller.add("South",errmsg);
    
      caller.setVisible(true);
      
      return;
    } 
	
	
		// create a template to indicate what we are interested in
		Tuple deviceTemplate = new Tuple("X10Device", 
								new Field(String.class),  // address
								new Field(String.class),  // name
							  new Field(Integer.class),  // type
	              new Field(String.class),  // description
	              new Field(X10Device.class)  // X10Device as serialized object

								);
    // place ourselves on the list to notified when anyone anywhere
    // writes a matching Tuple to this TupleSpace.            
    int seqNum = TSServer.eventRegister(TupleSpace.WRITE,deviceTemplate, this);
    // During initialization, we need to read all the previousls defined 
    // X10Device Tuples stored the TSpaces server. So we issue the 
    // scan() request to the tupleSpace using a template. This returns
    // a tuple whose fields are each tuples, one for each tuple that matched the
    // template. The tuple.fields() method returns an enumeration that can be
    // followed to access each individual Tuple. Once the individual Tuple is
    // accessed, the getFields(int) 
        // create a template to indicate what we are interested in
    
        // Issue the TupleSpace.scan() command.
    Tuple tupleSet = TSServer.scan(deviceTemplate);
    Debug.out(tupleSet);
    if ( tupleSet != null) {
      // Each Field of tupleSet is one of the X10Device tuples
      Enumeration e = tupleSet.fields();    
      while (  e.hasMoreElements() ) { 
        // enumerate over the set of tuples
        Field f = (Field)e.nextElement();
        //Debug.out("Tuple " + f);
        
        Tuple tuple = (Tuple)f.getValue();        
        String address = (String)tuple.getField(1).getValue();
        String name = (String)tuple.getField(2).getValue();
        Debug.out(tuple);
        X10DevicePanel devPanel = 
          new X10DevicePanel(TSServer,address,name);
        this.add(devPanel);
      }
    }
	
  } catch (Exception e)  { 
     Debug.out( e);
     
     Msg = e.getMessage();
     Failed = true;
	} catch (Error err)  { 
     	Debug.out( err);
     	
     	Msg = err.getMessage();
     	Failed = true;
	}
    
  
  if (Failed) {
    Label errmsg = new Label("TSpaces connection failure: "+ Msg);
    caller.add("South",errmsg);
  
    caller.setVisible(true);      
    return;
  }

    
    //Debug.out("Scan for current status");
    //
 

	

  //Debug.out("Now paint initial screen");
  Graphics g = this.getGraphics();
  if ( g == null)  {
    Debug.out("No graphic context");
    
    return;
  }  

  this.paint(g);
    
    

} // init
  

    /*
    ***************************************************************************
    ** ** term **
    ** *****************
    */
    /**
    ** This is called when the windowClosing event 
    ** arrives.  We will tell the server that we are going away by 
    ** issuing the cleanup() command.
    ** 
    ** @see TupleSpace#cleanup
    ** 
    *************************************************************************** 
    */
public void
term() {
	//Debug.out("term()");
	try {
		
		TSServer.cleanup();
	} catch (Exception tse) {
		Debug.out("term(): " + tse.getMessage());
		tse.printStackTrace();
	}
}  

	/*
    ***************************************************************************
    ** ** removeAll **
    ** *****************
    */
    /**
    ** This is called our parent (X10View) gets a applet destroy()
    ** event.  We will tell the server that we are going away by 
    ** issuing the term() command.
    **     
    *************************************************************************** 
    */
public void
removeAll() {
	super.removeAll();
	term();
	
}  
 


    /*
    ***************************************************************************
    ** ** call **
    ** **********
    */
    /**
    ** Process the callback from the server that notifies us when anyone 
    ** (including ourselfes) writes to the X10View TupleSpace.
    ** If we get back 2 empty vectors, then this was an erase request
    ** from one of our users.  Otherwise, the 2 vectors are the
    ** lines/points and colors that one of our users is publishing
    ** 
    ** @param eventName_ the name of the event command that caused this call, that is the
    ** name of the client side command of the thread that registered this call, e.g., in the
    ** case of a read, this would be TupleSpace.READ, **not** TupleSpace.WRITE which is the
    ** corresponding command that caused the actaul event.
    ** @param tsName_ the name of the tuple space this command was executed on.
    ** @param sequenceNumber_ the sequenceNumber for this event/command
    ** @param tuple_ the returned tuple or a Tuple with an exception inside
    ** @param isException_ was the command processed normaly or was there an exception
    **
    ** @return true if this is the last call this sequence # should be getting otherwise false
    *************************************************************************** 
    */
    public synchronized boolean 
    call(String eventName_, String tsName_, int sequenceNumber_, SuperTuple tuple_, 
										boolean isException_) {
				
		// Normally we should wake up some other
		// thread and queue up the info for it.
		// Remember, this code is being run in the thread
		// that handles callbacks from the server so make it quick here please.
	/****	
		System.err.println("callback for " + eventName_ 
			 + ", TupleSpace = " + tsName_  
			 + ",Seq #=" + sequenceNumber_  
			 + ",Tuple="  +	 tuple_ 
			 + ", isException=" + isException_);
	****/
	    // Get the 2 vectors from the Tuple that we recieved.
		try {
            String address = (String)(tuple_.getField(1).getValue());
            
     }  catch(TupleSpaceException tse) {
            Debug.out("com.ibm.tspaces.examples.x10View.X10ViewPanel::call TupleSpaceException " + tse.getMessage());
            Failed = true;
            return false;
     } // catch
       
     return false;
 } // call
    
        /*
    ***************************************************************************
    ** ** paint **
    ** ***********
    */
    /**
    ** Paints the panel.  
    ** The real paint method is called first for the objects that
    ** this user has generated, and then for a vector of objects
    ** that have been recieved form TupleSpace.
    **
    ** If an Erase request was received from TupleSpace then the 
    ** EraseFlag was set and we will erase the window before 
    ** proceeding.  
    **
    ** @param g - the graphics context
    *************************************************************************** 
    */
    public void paint(Graphics g) {
    	//Debug.out("paint() ");
    	if ( ! X10View.PaintOK )   // If iconified
    		return;
    
	
    }
    
   

} // X10ViewPanel

/*
$History: X10ViewPanel.java $
 * 
 * *****************  Version 1  *****************
 * User: Jthomas      Date: 2/03/99    Time: 10:58a
 * Created in $/GCS/Development/TSpaces/Java/com/ibm/tspaces/examples/x10
 
*/
/* $Log: X10ViewPanel.java,v $
/* Revision 2.1  1999/11/05 22:22:41  estesp
/* Update revision number to 2.1 on all files
/*
/* Revision 1.1.1.1  1999/11/05 16:24:54  estesp
/* Imported 2.1.0 release into Austin CVS
/*
 * Revision 1.3  1999/11/03 16:09:14  jthomas
 * Minor cleanup while testing with Jeode
 *
 * Revision 1.2  1999/06/17 05:39:50  thodes
 *   Updated the inital checkin to append the "Log" field and
 * convert CR/LF to CR (for win/unix interop).
 *
 *   The inital checkin lower-cased directrory names, and omitted
 * many dirs/files that will added later, e.g., MoDAL stuff.
 *
 * All of the above will need to be done to all VSS-to-CVS
 * converted sources.  In summary, in moving from VSS to CVS, do this:
 *  - lower-case dir names
 *  - CR/LF --> CR
 *  - append CVS "Log" entties
 *
 * (a script that helps with #2 and #3 is in
 *     tspaces1:~thodes/bin/update-keywords.sh)
 * 
 */


